package gupao.concurrency.states;

import lombok.Getter;
import lombok.RequiredArgsConstructor;

import java.lang.reflect.Field;

@RequiredArgsConstructor
public class ImmutableLink<E> {
    @Getter
    @RequiredArgsConstructor
    public static
    final class Node<E>{
        private final E item;
        private final Node<E> next;
    }
    @Getter
    private final Node<E> head;
    private volatile int val = 0;
    private static final Field NEXT_FIELD_HACK;
    static {
        try {
            NEXT_FIELD_HACK = Node.class
                    .getDeclaredField("next");
            NEXT_FIELD_HACK.setAccessible(true);
        } catch (NoSuchFieldException e) {
            throw new Error("this is error bug.");
        }
    }

    public ImmutableLink<E> addHeader(Node<E> node){
        try {
            NEXT_FIELD_HACK.set(node, head);
            val = 1;
        } catch (IllegalAccessException e) {
            throw new RuntimeException(e);
        }
        return new ImmutableLink<>(node);
    }

    public ImmutableLink<E> removeHeader(){
        if(head == null){
            return this;
        }
        Node<E> newHead = head.next;
        try {
            NEXT_FIELD_HACK.set(head, null);
            val = 1;
        } catch (IllegalAccessException e) {
            throw new RuntimeException(e);
        }
        return new ImmutableLink<>(newHead);
    }
}
